from abc import abstractmethod

import pygame

from Lib.Core.UIBase import UIBase
from constants import config
from Lib import UtilsGame
from Lib.Core.UISprite import UISprite


class UIAutoText(UIBase):
    def __init__(self, rect, layer, text, width, font_size, font_color, offset=None, rule=None, delay=50,
                 line_height=5):
        super().__init__(rect, layer)
        self._time = 0
        self._index_line = 0
        self._index_text = 0
        self.index_text = 0
        self.is_run = True
        self.text = text
        self.font = pygame.font.Font(config.get("base", "font_path"), font_size)
        self.font_size = font_size
        self.font_color = font_color
        self.list_text = self.GeneratorLineText(text)
        self.line_height = font_size + line_height
        self.delay = delay
        self.rule = rule
        size = width, len(self.list_text) * self.line_height
        self.surface = UtilsGame.GeneratorAlphaSurface(size)
        sp = UISprite(self.surface)
        sp.rect.topleft = offset
        self.add(sp)
        self.action_update = self.Auto
        self.action_mouse_button_down = self.Click

        self.InitAction()

    def GeneratorLineText(self, text):
        _list = {}
        line_text = str(text).split("\n")
        for line in range(len(line_text)):
            if line not in _list: _list[line] = []
            for char in line_text[line]:
                _list[line].append(self.font.render(char, True, self.font_color, None))
        return _list

    def Auto(self, dt):
        if self.is_run:
            self._time += dt
            delay = self.rule[self.index_text] if self.rule and self.index_text in self.rule else self.delay
            if self._time >= delay:
                self._time = 0
                self.index_text += 1
                _text_len = len(self.list_text[self._index_line])
                if self._index_text >= _text_len:
                    self._index_line += 1
                    self._index_text = 0
                if self._index_line >= len(self.list_text):
                    self.is_run = False
                else:
                    __text = self.list_text[self._index_line]
                    pos = [self._index_text * self.font_size, self._index_line * self.line_height]
                    self.surface.blit(self.list_text[self._index_line][self._index_text], pos)
                    self._index_text += 1

    def Click(self, pos, buttons):
        if buttons:
            if self.is_run:
                self.delay = 0
            else:
                self.StopClick()

    @abstractmethod
    def StopClick(self):
        ...
